package com.dlc.apk.base

import android.Manifest
import android.app.ProgressDialog
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.widget.Toast
import androidx.annotation.CallSuper
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment
import com.dlc.apk.R
import com.dlc.apk.utils.LogPlus
import com.dlc.apk.utils.ToastUtil

/**
 * @author We
 */
abstract class BaseActivity : AppCompatActivity() {
    protected var viewDataBinding: ViewDataBinding? = null
    private var progressDialog: ProgressDialog? = null
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        LogPlus.e("### onCreate,activity->" + this.javaClass.simpleName)
        viewDataBinding = DataBindingUtil.setContentView(this, getLayoutId())
        viewDataBinding!!.lifecycleOwner = this
        //进行UI model 实例化
        initViewModels()
        //进行业务层Service初始化
        initServices()
        initProgressDialog()
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            requestPermissions(permissions, 1)
            return
        }
        init()
    }

    private fun initProgressDialog() {
        progressDialog = ProgressDialog(this)
        progressDialog!!.setMessage("")
        progressDialog!!.setCancelable(true)
        progressDialog!!.setCanceledOnTouchOutside(true)
    }

    /**
     * layout id
     *
     * @return
     */
    protected abstract fun getLayoutId(): Int

    /**
     * 实例化双向数据绑定需要用到的models
     */
    protected abstract fun initViewModels()

    /**
     * 实例化业务层Service
     */
    protected abstract fun initServices()

    @CallSuper
    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        for (grantResult in grantResults) {
            if (grantResult != PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(this, "权限已拒绝", Toast.LENGTH_LONG).show()
                BaseApp.instance.restartApp((1000 * 3).toLong())
                return
            }
        }
        init()
    }

    protected abstract fun init()
    fun <T> getViewDataBinding(): T? {
        return viewDataBinding as T?
    }

    fun showProgressDialog(msg: String?) {
        runOnUiThread {
            progressDialog!!.setMessage(msg)
            progressDialog!!.show()
        }
    }

    fun dismissProgressDialog() {
        runOnUiThread {
            progressDialog?.dismiss()
        }
    }

    fun showToast(resId: Int) {
        ToastUtil.show(this, resId)
    }

    fun showToast(text: String?) {
        ToastUtil.show(this, text)
    }

    fun showOneToast(resId: Int) {
        ToastUtil.showOne(this, resId)
    }

    fun showOneToast(text: String?) {
        runOnUiThread { ToastUtil.showOne(this, text, R.mipmap.ic_info) }
    }

    override fun onStart() {
        super.onStart()
        LogPlus.e("###onSrart,activity->" + this.javaClass.simpleName)
    }

    override fun onRestart() {
        super.onRestart()
        LogPlus.e("###onRestart,activity->" + this.javaClass.simpleName)
    }

    override fun onResume() {
        super.onResume()
        LogPlus.e("###onResume,activity->" + this.javaClass.simpleName)
    }

    override fun onPause() {
        super.onPause()
        LogPlus.e("###onPause,activity->" + this.javaClass.simpleName)
    }

    @CallSuper
    override fun onDestroy() {
        super.onDestroy()
        LogPlus.e("###onDestroy,activity->" + this.javaClass.simpleName)
    }

    private var mainFragment: BaseFragment? = null
    fun loadRootFragment(layoutId: Int, fragment: BaseFragment) {
        addFragment(layoutId, fragment, null, false, true)
        lastShowFragment = fragment
        mainFragment = fragment
    }

    fun addFragment(layoutId: Int, fragment: BaseFragment, hidePreFragment: Boolean) {
        addFragment(layoutId, fragment, null, true, hidePreFragment)
    }

    private var lastShowFragment: BaseFragment? = null

    @JvmOverloads
    fun addFragment(
        layoutId: Int,
        fragment: BaseFragment,
        tag: String? = null,
        addToBackStack: Boolean = true,
        hidePreFragment: Boolean = true
    ) {
        val fragmentManager = supportFragmentManager
        val fragmentTransaction = fragmentManager.beginTransaction()
        if (fragment.isAdded) {
            fragmentTransaction.show(fragment)
        } else {
            fragmentTransaction.add(layoutId, fragment, tag)
            /*fragmentTransaction.replace(layoutId, fragment, tag);*/
            if (addToBackStack) {
                fragmentTransaction.addToBackStack(null) //添加到回退栈
            }
        }
        if (hidePreFragment && lastShowFragment != null) {
            LogPlus.e("###lastShowFragment -> " + lastShowFragment!!.javaClass.simpleName)
            //
            lastShowFragment!!.onHiddenChanged(true)
            fragmentTransaction.hide(lastShowFragment!!)
        }
        lastShowFragment = fragment
        fragmentTransaction.commitAllowingStateLoss()
        LogPlus.e("###backStackCount->" + fragmentManager.backStackEntryCount)
    }

    val fragments: List<Fragment?>
        get() {
            val fragmentManager = supportFragmentManager
            return fragmentManager.fragments
        }

    fun isInBackStack(clazz: Class<out BaseFragment?>): Boolean {
        val fragmentManager = supportFragmentManager
        for (fragment in fragmentManager.fragments) {
            if (fragment == null) {
                continue
            }
            if (fragment.javaClass == clazz) {
                return true
            }
        }
        return false
    }

    fun popBackStack() {
        if (lastShowFragment != null) {
            hideFragment(lastShowFragment)
        }
        //回退栈 pop
        supportFragmentManager.popBackStack()

        if (fragments.isEmpty()) {
            mainFragment?.onHiddenChanged(false)
            mainFragment?.onResume()
            return
        }

        if (fragments.size >= 2) {
            val frag = fragments[fragments.size - 1 - 1]
            if (frag is BaseFragment) {
                lastShowFragment = frag

                lastShowFragment?.onHiddenChanged(false)
                lastShowFragment?.onResume()
            }
        }
    }

    private fun hideFragment(lastShowFragment: BaseFragment?) {
        val fragmentManager = supportFragmentManager
        val fragmentTransaction = fragmentManager.beginTransaction()
        if (lastShowFragment != null) {
            lastShowFragment.onHiddenChanged(true)
            fragmentTransaction.hide(lastShowFragment)
        }
        fragmentTransaction.commitAllowingStateLoss()
    }

    fun popAll() {
        val fragmentManager = supportFragmentManager
        val count = fragmentManager.backStackEntryCount
        for (i in 0 until count) {
            fragmentManager.popBackStack()
        }
        fragmentManager.fragments.clear()

        mainFragment?.onHiddenChanged(false)
    }//得到回退栈中的当前总的个数，每添加一次回退栈该数会加1

    /**
     * 得到回退栈中的当前总的个数
     *
     * @return
     */
    val fragmentBackStackCount: Int
        get() =//得到回退栈中的当前总的个数，每添加一次回退栈该数会加1
            supportFragmentManager.backStackEntryCount

    /**
     * 栈顶 fragment
     *
     * @return
     */
    val topFragment: BaseFragment?
        get() {
            val fragmentList = supportFragmentManager.fragments
            return if (fragmentList.size == 0) {
                null
            } else {
                val frag = fragmentList[fragmentList.size - 1]
                if (frag is BaseFragment) frag else null
            }
        }

    /**
     * 栈顶 fragment
     *
     * @return
     */
    val backFragment: BaseFragment?
        get() {
            val fragmentList = supportFragmentManager.fragments
            return if (fragmentList.size < 3) {
                null
            } else {
                val frag = fragmentList[fragmentList.size - 2]
                if (frag is BaseFragment) {
                    frag
                } else null
            }
        }

    /**
     * 栈底 fragment
     *
     * @return
     */
    val rootFragment: BaseFragment?
        get() {
            val fragmentList = supportFragmentManager.fragments
            return if (fragmentList.size == 0) {
                null
            } else fragmentList[0] as BaseFragment
        }

    override fun onBackPressed() {
        val canBack = fragmentBackStackCount > 0
        if (canBack) {
            popBackStack()
            //topFragment?.onResume2()
            return
        }
        super.onBackPressed()
    }

    companion object {
        protected var permissions = arrayOf(
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.READ_PHONE_STATE
        )
    }
}